package ru.ifmo.ipimenov.ewf_svn.standalone.controller;

import org.apache.commons.logging.LogFactory;
import org.apache.commons.logging.Log;
import org.tmatesoft.svn.core.internal.io.dav.DAVRepositoryFactory;
import org.tmatesoft.svn.core.internal.io.svn.SVNRepositoryFactoryImpl;
import org.tmatesoft.svn.core.internal.io.fs.FSRepositoryFactory;
import org.tmatesoft.svn.core.auth.BasicAuthenticationManager;
import org.tmatesoft.svn.core.wc.SVNCommitClient;
import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.SVNException;

import javax.swing.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.io.File;

import ru.ifmo.ipimenov.ewf_svn.standalone.model.db.Document;
import ru.ifmo.ipimenov.ewf_svn.standalone.model.db.Category;
import ru.ifmo.ipimenov.ewf_svn.standalone.model.list.Item;
import ru.ifmo.ipimenov.ewf_svn.standalone.model.list.Model;
import ru.ifmo.ipimenov.ewf_svn.standalone.model.UserProvider;
import ru.ifmo.ipimenov.ewf_svn.standalone.model.CategoryProvider;
import ru.ifmo.ipimenov.ewf_svn.standalone.model.StateProvider;
import ru.ifmo.ipimenov.ewf_svn.standalone.dao.impl.CategoryDaoHibernate;
import ru.ifmo.ipimenov.ewf_svn.standalone.repository.SvnUrlProvider;
import ru.ifmo.ipimenov.ewf_svn.standalone.service.DocumentService;
import ru.ifmo.ipimenov.ewf_svn.standalone.service.impl.DocumentServiceImpl;

/**
 * @author: Ilya Pimenov
 * Scartel Starlab company
 */
public class AddAction implements ActionListener {
    /**
     * Logger for all purposes
     */
    private static Log log = LogFactory.getLog(AddAction.class);

    private JList list;

    public AddAction(JList list) {
        this.list = list;
    }

    public void actionPerformed(ActionEvent e) {
        JFileChooser c = new JFileChooser();
        c.setFileSelectionMode(JFileChooser.FILES_ONLY);
        // Demonstrate "Open" dialog
        int rVal = c.showOpenDialog(list);
        if (rVal == JFileChooser.APPROVE_OPTION) {
            log.debug(c.getSelectedFile().getName());
            File f = c.getSelectedFile();
            Document d = new Document();
            
            //"other" category by default
            Category category = CategoryProvider.getInstance().load(3);
            d.setCategory(category);
            d.setHolder(UserProvider.getInstance().getUser());
            d.setName(f.getName());
            d.setState(StateProvider.getInstance().load(category).get(0));
            SVNURL url = SvnUrlProvider.getUrl(f.getName());
            d.setUrl(url.toString());
            DocumentService ds = new DocumentServiceImpl();
            ds.save(d);


            Item i = new Item(f.getName(), url, f, d);
            i.setStatus(Item.ADDED);
            addSelected(i);
            ((Model)list.getModel()).add(i);
            list.updateUI();

            log.info("By idea document is added to the repository");
        }
        if (rVal == JFileChooser.CANCEL_OPTION) {
            log.debug("You pressed cancel");
        }
    }

    private void addSelected(Item i) {
        DAVRepositoryFactory.setup();
        SVNRepositoryFactoryImpl.setup();
        FSRepositoryFactory.setup();

        BasicAuthenticationManager iam = new BasicAuthenticationManager("ilya.pimenov", "n7s9m9d3");
        iam.setAuthenticationForced(true);
        SVNCommitClient client = new SVNCommitClient(iam, null);

        client.setIgnoreExternals(true);
        try {
            client.doImport(i.getFile(), updateWithAuth(i.getUrl()), "Deployed new version of document", true, false);
        } catch (SVNException e) {
            log.error("Failed to import to svn server. " + e);
        }
    }

    private SVNURL updateWithAuth(SVNURL url) {
        SVNURL u = null;
        try {
            u = SVNURL.create("https", "ilya.pimenov:n7s9m9d3", url.getHost(), 443, url.getPath(), true);
        } catch (SVNException e) {
            log.error("Failed to update uri");
        }
        log.info("Updated url = " + u.toString());
        return u;
    }
}
